#ifndef __IRR__C_NETWORK_DRIVER_INCLUDED__
#define __IRR__C_NETWORK_DRIVER_INCLUDED__

//#include "IrrCompileConfig.h"

#include "INetworkDriver.h"
#include "ISocketLow.h"
#include "CSocketLow.h"

#ifdef _IRR_PSP_
#include <sys/fd_set.h>
#endif

namespace game
{
	namespace net
	{

        class CNetworkCallback : public INetworkCallback 
		{

		public:

            CNetworkCallback();
            ~CNetworkCallback();
			//! This event is called when a socket is closed
            virtual void onClose(ISocket* Socket);

			//! This event is called when data is received
			virtual void onDataReceive(ISocket* Socket);

			//! This event is called when a socket has succesfully connected
			virtual void onConnect(ISocket *Socket);

			//! This event is called when an error occours
			virtual void onError(ISocket *Socket);

			//! This event is called when the wifi connection is estabilished
			//! \param Connected: If true the wifi has estabilished a connection
			virtual void onWiFiStatusChange(bool Connected);
		};


		class CNetworkDriver : public INetworkDriver
		{
		public:
			CNetworkDriver();

            virtual ~CNetworkDriver();

			//! Initialize the wifi connections
			/**
			\param ApctlIndex: apctl config index
			\param NetworkCallback: an object that extends the INetworkCallback interface
			\return Returns true if wifi was succesfully initialized */
			virtual void initialize(INetworkCallback *NetworkCallback, int ApctlIndex = 1 );

			//! Close the wifi connection
			virtual void disconnectApctl();

			//! Create a socket
			/** \param HostName: hostname or ip address to connect to, if this param is ommitted the socket will not be connected
			\param Port: the port number
			\return Returns the created socket
			When the socket succesfully connects the event onConnect is raised, otherwise the event onError will be called.
			*/
			virtual ISocketLow* createSocket(c8 *HostName = 0, int Port = 0);

			//! Get the socket with the index specified
			//! \param Index: the socket index you want to get
			//! \return Returns the socket class
			virtual ISocketLow* getSocketByIndex(int index);


			//! Gets the local ip
			//! \return Return the local ip address
			virtual irr::core::stringc& getLocalAddress();

			virtual void removeSocket(ISocketLow *socket);

			virtual bool getConnectionInitialized();

			virtual INetworkCallback* getNetworkCallback();

			virtual void run();


			ISocketLow* searchFromSocket(int sock);

		private:
			
			bool ModulesLoaded;
			
			bool LastStatus;
			
			irr::core::stringc localip;
			
			irr::core::array<ISocketLow*> cache;
			
			int socketIndexStart;
			
			bool Connecting;

			bool ConnectionInitialized;

			INetworkCallback*  NetworkCallback;

		};
	}
}

#endif

